import { createFileRoute } from '@tanstack/react-router'
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
import { Skeleton } from "@/components/ui/skeleton"
import {
    Table,
    TableBody,
    TableCell,
    TableHead,
    TableHeader,
    TableRow,
} from "@/components/ui/table"
import { type Expense } from '@server/sharedTypes'
import { deleteExpense, expensesQueryOptions, loadingCreateExpenseQueryOptions } from '@/lib/api'
import { Button } from '@/components/ui/button'
import { Trash } from 'lucide-react'
import { toast } from 'sonner'


export const Route = createFileRoute('/_authenticated/expenses')({
    component: Expenses,
})


function ExpenseSkeleton() {
    return Array.from({ length: 5 }).map((_, i) => (
        <TableRow key={i}>
            <TableCell>
                <Skeleton className="h-[20px] w-[100px] rounded-full" />
            </TableCell>
            {
                Array.from({ length: 4 }).map((_, i) => (
                    <TableCell key={i}>
                        <Skeleton className="h-[20px] rounded-full" />
                    </TableCell>
                ))

            }
        </TableRow>
    ))
}

function ExpenseDeleteButton({ id }: { id: number }) {
    const queryClient = useQueryClient()
    const mutation = useMutation({
        mutationFn: deleteExpense,
        onError: () => {
            toast("Failed to delete expense")
        },
        onSuccess: () => {
            queryClient.setQueryData(expensesQueryOptions.queryKey, (existingExpenses) => {
                return {
                    ...existingExpenses,
                    expenses: existingExpenses!.expenses.filter(expense => expense.id !== id)
                }
            })
            toast("Successfully deleted expense")
        }
    })
    return <Button variant="outline" size="icon" className="cursor-pointer" disabled={mutation.isPending} onClick={() => mutation.mutate(id)}>
        {mutation.isPending ? "..." : <Trash className="h-4 w-4" />}
    </Button>
}


function ExpensesTable({ data, isPending }: { data: Expense[], isPending: boolean }) {
    const { data: loadingExpense } = useQuery(loadingCreateExpenseQueryOptions)
    return <Table>
        <TableHeader>
            <TableRow>
                <TableHead className="w-[100px]">Id</TableHead>
                <TableHead>Title</TableHead>
                <TableHead>Amount</TableHead>
                <TableHead>Date</TableHead>
                <TableHead>Delete</TableHead>
            </TableRow>
        </TableHeader>
        <TableBody>
            {
                loadingExpense?.expense && (
                    <TableRow>
                        <TableCell>1</TableCell>
                        <TableCell>{loadingExpense.expense.title}</TableCell>
                        <TableCell>{loadingExpense.expense.amount}</TableCell>
                        <TableCell>{loadingExpense.expense.date.split(" ")[0].replaceAll('/', '-')}</TableCell>
                        <TableCell>
                            <Button variant="outline" size="icon" disabled className="cursor-pointer">
                                <Trash className="h-4 w-4" />
                            </Button>
                        </TableCell>
                    </TableRow>
                )
            }
            {
                isPending ? <ExpenseSkeleton /> :
                    data?.map((expense, idx) => (
                        <TableRow key={expense.id}>
                            <TableCell>{idx + 1 + (loadingExpense?.expense ? 1 : 0)}</TableCell>
                            <TableCell>{expense.title}</TableCell>
                            <TableCell>{expense.amount}</TableCell>
                            <TableCell>{expense.date}</TableCell>
                            <TableCell>
                                <ExpenseDeleteButton id={expense.id} />
                            </TableCell>
                        </TableRow>
                    ))

            }
        </TableBody>
    </Table>
}
function Expenses() {
    const { isPending, error, data } = useQuery(expensesQueryOptions)

    if (error) return 'Failed to fetch expenses'

    return <ExpensesTable data={data?.expenses as unknown as Expense[]} isPending={isPending} />

}
